package cs423.loadBalancer.core;

import java.io.File;
import java.nio.ByteBuffer;
import java.util.List;

//This class is intended to initiate the processing phase
//as well as initiate the aggregation phase
public class ProcessingPhase implements Runnable{

	int type;
	byte[]ori_data;
	int width;
	double multiplier;
	int height;
	double [][] big_data;
	int interval;
	String kind;
	
	public ProcessingPhase(){}
	public ProcessingPhase(byte[] data, double multiplier, int type, int width, String kind){
		this.ori_data=data;
		this.multiplier = multiplier;
		this.type = type;
		this.width = width;
		this.kind = kind;
	}
	
	public void run(){
	
		//convert byte data into double data
		big_data = Util.convertByteToDouble2D(ori_data, width);
		Main.data = big_data;
		
		interval = width/8;
		Main.interval = interval;
		//NOTICE ABOVE about the problem of the interval, if it is the last one,
		//might need less than width/4
		
		//Interval has to be divided by the width
		Main.cut_pos = Util.cutData(big_data,interval, kind);
		Main.initial_q_size = Main.cut_pos.size();
		
		//try printing out the whole matrix
		
		privateProcess();
		
	}
	
	//a private process that takes care the process
	private void privateProcess() {
		
		Thread tm = new Thread(new TransferManager());
		Thread a = new Thread(new Adaptor());
		Thread hm = new Thread(new HardwareMonitor());
		Thread wt = new Thread(new WorkerThread());
		Thread sm = new Thread(new StateManager());
		
		tm.setDaemon(true);
		a.setDaemon(true);
		sm.setDaemon(true);
		hm.setDaemon(true);
		wt.setDaemon(true);
		
		tm.start();
		a.start();
		sm.start();
		hm.start();
		wt.start();


		try {
			//Main.finish.lock();
			Main.finish_cv.acquire();
		} catch (InterruptedException e) {
			System.out.println("Main.finish_cv.await() ");
			e.printStackTrace();	
		}	//finally{
			//Main.finish.unlock();
		//}
		
		Main.tm_cv.release();
		Main.a_cv.release();
		Main.hm_cv.release();
		Main.wt_cv.release();
		Main.sm_cv.release();
		
		HardwareMonitor.timer.cancel();
		try {
			tm.join();
			a.join();
			hm.join();
			wt.join();
			sm.join();
		} catch (InterruptedException e1) {
			System.out.println("HAVING PROBLEM JOINING THERADS AT END");
			e1.printStackTrace();
		}	
		finally{

			Thread agg = new Thread(new Aggregation(Main.func_kind));
			agg.start();
			try {
				agg.join();
			} catch (InterruptedException e) {
				System.out.println("AGG JOIN EXCEPTION, WILL RETURN");
				e.printStackTrace();
			}
		
		}
		
	}
	
}
